//
//  NSString+Category.m
//  VICategory
//
//  Created by MN on 2022/7/4.
//

#import "NSString+Category.h"
#import <CommonCrypto/CommonCrypto.h>

NSString * const kVISecretKey = @"thank,cloudstore";


@implementation NSString (Category)
- (CGFloat)vi_widthWithFontSize:(CGFloat)fontSize{
    
    CGFloat textWith = [self boundingRectWithSize:CGSizeMake(2000, MAXFLOAT)
                                      options:NSStringDrawingUsesLineFragmentOrigin
                                   attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
                                      context:nil].size.width;
    return textWith;
}

//保存本地的文件名称
- (NSString *)vi_fileName{
   NSFileManager *fileManager = [NSFileManager defaultManager];
   NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
   NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:self];
   if ([fileManager fileExistsAtPath:path]) {
       [fileManager removeItemAtPath:path error:nil];
   }
   [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
   
   return path;
}

+ (NSString *)vi_thousandsFormat:(NSString *)string {
    if (!string || string.length == 0) {
        return string;
    }
    NSNumber *number = @([string doubleValue]);
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    formatter.numberStyle = NSNumberFormatterDecimalStyle;
    formatter.positiveFormat = @"###,##0";
    NSString *amountString = [formatter stringFromNumber:number];
    return amountString;
}

- (NSMutableAttributedString *)vi_keyWords:(NSString *)keyWords withKeyWordsColor:(UIColor *)color {
    NSMutableAttributedString *mutableAttributedStr = [[NSMutableAttributedString alloc] initWithString:self];
    if (color == nil) {
        color = [UIColor redColor];
    }
    if (keyWords.length <= 0) {
         return mutableAttributedStr;
    }
    for (NSInteger j = 0; j <= keyWords.length-1; j++) {
        
        NSRange searchRange = NSMakeRange(0, [self length]);
        NSRange range;
        NSString *singleStr = [keyWords substringWithRange:NSMakeRange(j, 1)];
        while
            ((range = [self rangeOfString:singleStr options:0 range:searchRange]).location != NSNotFound) {
                //改变多次搜索时searchRange的位置
                searchRange = NSMakeRange(NSMaxRange(range), [self length] - NSMaxRange(range));
                //设置富文本
                [mutableAttributedStr addAttribute:NSForegroundColorAttributeName value:color range:range];
                
            }
    }
    return mutableAttributedStr;
}


- (NSString *)getSDCardMessage{
    // 表示存储卡状态，取值：1、2、3，分别表示：无存储卡、存储卡异常、正常，默认无存储卡（1）
    NSInteger state = [self integerValue];
    NSString *value;
    if (state == 1) {
        value = @"无存储卡";
    }else if (state == 2){
        value = @"存储卡异常";
    }else{
        // errorcode -37读取失败，超时等情况
        value = @"未检测到存储空间";
    }
    return value;
}

//判断字符串是否为空
+ (BOOL)isEmptyStr:(NSString*)string {
    if ([string isKindOfClass:[NSNull class]] || [string isEqualToString:@""] || string == nil || [string isEqualToString:@"(null)"] || [string isEqualToString:@"<null>"] || [string isEqualToString:@"null"] || [[string  stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]isEqualToString:@""]){
        return YES;
    }
    return NO;
}

/// 手机号有效性验证
+ (BOOL)isMobileNumber:(NSString *)number {
    ///手机号以13、15、18、170...开头，8个 \d 数字字符
    NSString *mobileNoRegex = @"^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$";
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",mobileNoRegex];
    return [pre evaluateWithObject:number];
}

+ (BOOL)isNumberLetterSpecial:(NSString *)password upperAndLower:(BOOL)upperAndLower {
    NSString *pwdRegex;
    if (upperAndLower) {
        pwdRegex = @"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[~!@#$%^&*:;,.=?$\x22]).{8,20}$";
    }else {
        pwdRegex = @"^(?=.*[0-9])(?=.*[a-z])(?=.*[~!@#$%^&*:;,.=?$\x22]).{8,20}$";
    }
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",pwdRegex];
    return [pre evaluateWithObject:password];
}

/// 手机号脱敏(中间4位加*号)
+ (NSString *)phoneNumberDesensitization:(NSString*)number {
//    if ([self isMobileNumber:number]) {
    if (number.length < 7) return number;
        NSString *numberString = [number stringByReplacingCharactersInRange:NSMakeRange(3, 4) withString:@"****"];
        return numberString;
//    }
//    return number;
}

+ (NSString *)scaleTime:(CGFloat)duration {
    if (duration < 60) {
        return [NSString stringWithFormat:@"%.f秒",duration];
    } else if (duration < 3600) {
        return [NSString stringWithFormat:@"%.f分钟%d秒",duration / 60,(int)duration % 60];
    } else if (duration < 24 * 3600) {
        return [NSString stringWithFormat:@"%.f小时%d分钟%d秒",duration / 3600, (int)duration % 3600 / 60,(int)duration % 60];
    }
    return [NSString stringWithFormat:@"%.f天",duration/24/3600];
}

+ (BOOL)isBlankString:(NSString *)aStr {
    return [self isEmptyStr:aStr];
}

+ (BOOL)containsEmoji:(NSString *)string {
    if ([self isNineKeyBoard:string]) {
        return NO;
    }
    __block BOOL isEomji = NO;
    [string enumerateSubstringsInRange:NSMakeRange(0, [string length])
                               options:NSStringEnumerationByComposedCharacterSequences
                            usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
        const unichar hs = [substring characterAtIndex:0];
        if (0xd800 <= hs && hs <= 0xdbff) {
            if (substring.length > 1) {
                const unichar ls = [substring characterAtIndex:1];
                const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                if (0x1d000 <= uc && uc <= 0x1f77f) {
                    isEomji = YES;
                }
            }
        } else if (substring.length > 1) {
            const unichar ls = [substring characterAtIndex:1];
            if (ls == 0x20e3|| ls == 0xfe0f) {
                isEomji = YES;
            }
        } else {
            if (0x2100 <= hs && hs <= 0x27ff && hs != 0x263b) {
                isEomji = YES;
            } else if (0x2B05 <= hs && hs <= 0x2b07) {
                isEomji = YES;
            } else if (0x2934 <= hs && hs <= 0x2935) {
                isEomji = YES;
            } else if (0x3297 <= hs && hs <= 0x3299) {
                isEomji = YES;
            } else if (hs == 0xa9
                       || hs == 0xae
                       || hs == 0x303d
                       || hs == 0x3030
                       || hs == 0x2b55
                       || hs == 0x2b1c
                       || hs == 0x2b1b
                       || hs == 0x2b50
                       || hs == 0x231a ) {
                isEomji = YES;
            }
        }
    }];
    return isEomji;
}

+ (BOOL)isNineKeyBoard:(NSString *)string {
    return [@"➋➌➍➎➏➐➑➒" containsString:string];
}

+ (NSInteger)stringLength:(NSString *)string {
    NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    NSData *data = [string dataUsingEncoding:enc];
    return [data length];
}

- (NSDictionary *)vi_jsonToDic{
    NSData *jsonData = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers
    error:&error];
    return error ? @{} : dic;
}

+ (NSString *)vi_AES128Encrypt:(NSString *)plainText key:(NSString *)key {
    char keyPtr[kCCKeySizeAES128+1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    char ivPtr[kCCBlockSizeAES128+1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [key getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    
    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [data length];
    
    int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
    NSInteger newSize = 0;
    
    if(diff > 0)
    {
        newSize = dataLength + diff;
    }
    
    char dataPtr[newSize];
    memcpy(dataPtr, [data bytes], [data length]);
    for(int i = 0; i < diff; i++)
    {
        dataPtr[i + dataLength] = 0x00;
    }
    
    size_t bufferSize = newSize + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    memset(buffer, 0, bufferSize);
    
    size_t numBytesCrypted = 0;
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          0x0000,               //No padding
                                          keyPtr,
                                          kCCKeySizeAES128,
                                          ivPtr,
                                          dataPtr,
                                          sizeof(dataPtr),
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
        return [resultData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    }
    free(buffer);
    return nil;
}

+ (NSString *)vi_AES128Decrypt:(NSString *)encryptText key:(NSString *)key
{
    char keyPtr[kCCKeySizeAES128 + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    char ivPtr[kCCBlockSizeAES128 + 1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [key getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    NSData *data = [[NSData alloc] initWithBase64EncodedData:[encryptText dataUsingEncoding:NSUTF8StringEncoding] options:0];
    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    
    size_t numBytesCrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          0x0000,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,
                                          [data bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
        NSString *hexString = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
        NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"\0"];
        NSString *trimmedString = [hexString stringByTrimmingCharactersInSet:set];
        return trimmedString;
    }
    free(buffer);
    return nil;
}


+ (NSString *)base64Encode:(NSString *)str {
   //base64加密
   NSData*data = [str dataUsingEncoding:NSUTF8StringEncoding];
   NSData*base64Data = [data base64EncodedDataWithOptions:0];//Data加密
   NSString*base64Str = [data base64EncodedStringWithOptions:0];//NSString加密
   return base64Str;
}

+ (NSString *)base64Decode:(NSString *)str {
   //base64解密
   NSData *data = [[NSData alloc]initWithBase64EncodedString:str options:0];
   NSString *decodeStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
   return decodeStr;
}

/**
 十进制转换十六进制
  
 @param decimal 十进制数
 @return 十六进制数
 */
+ (NSString *)vi_getHexByDecimal:(NSInteger)decimal {
    
    NSString *hex =@"";
    NSString *letter;
    NSInteger number;
    for (int i = 0; i<9; i++) {
        
        number = decimal % 16;
        decimal = decimal / 16;
        switch (number) {
                
            case 10:
                letter =@"A"; break;
            case 11:
                letter =@"B"; break;
            case 12:
                letter =@"C"; break;
            case 13:
                letter =@"D"; break;
            case 14:
                letter =@"E"; break;
            case 15:
                letter =@"F"; break;
            default:
                letter = [NSString stringWithFormat:@"%ld", (long)number];
        }
        hex = [letter stringByAppendingString:hex];
        if (decimal == 0) {
            
            break;
        }
    }
    return hex;
}

- (NSString *)vi_MD5{
    
    //1.首先将字符串转换成UTF-8编码, 因为MD5加密是基于C语言的,所以要先把字符串转化成C语言的字符串
    const char *fooData = [self UTF8String];
    
    //2.然后创建一个字符串数组,接收MD5的值
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    
    //3.计算MD5的值, 这是官方封装好的加密方法:把我们输入的字符串转换成16进制的32位数,然后存储到result中
    CC_MD5(fooData, (CC_LONG)strlen(fooData), result);
    // CC_MD5(fooData, (unsigned int)strlen(fooData), result);
    /**
     第一个参数:要加密的字符串
     第二个参数: 获取要加密字符串的长度
     第三个参数: 接收结果的数组
     */
    
    //4.创建一个字符串保存加密结果
    NSMutableString *saveResult = [NSMutableString string];
    // NSMutableString *saveResult = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    
    //5.从result 数组中获取加密结果并放到 saveResult中
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [saveResult appendFormat:@"%02x", result[i]];
    }
    /*
     x表示十六进制，%02X  意思是不足两位将用0补齐，如果多余两位则不影响
     NSLog("%02X", 0x888);  //888
     NSLog("%02X", 0x4); //04
     x大写或小写，输出也会相应转成大写或小写
     */
    return saveResult;
}

+ (NSString *)getRandomStr:(NSInteger)digit {
    char data[digit];
    for (int x = 0; x < digit; data[x++] = (char)('A' + (arc4random_uniform(26))));
    NSString *randomStr = [[NSString alloc] initWithBytes:data length:digit encoding:NSUTF8StringEncoding];
    NSString *string = [NSString stringWithFormat:@"%@",randomStr];
    return string;
}

@end
